package com.nbsaas.nbmall.customer.rest.resource;

import com.haoxuer.bigworld.member.data.dao.TenantUserDao;
import com.haoxuer.bigworld.member.data.entity.TenantUser;
import com.haoxuer.bigworld.member.data.enums.BindType;
import com.haoxuer.bigworld.member.data.request.UserRegisterRequest;
import com.haoxuer.bigworld.member.data.response.UserBasicResponse;
import com.haoxuer.bigworld.pay.api.domain.page.TradeStreamPage;
import com.haoxuer.bigworld.pay.rest.conver.TradeStreamSimpleConver;
import com.haoxuer.discover.generate.utils.RandomValue;
import com.haoxuer.discover.trade.api.domain.request.TradeRequest;
import com.haoxuer.discover.trade.api.domain.response.TradeResponse;
import com.haoxuer.discover.trade.data.dao.BasicTradeAccountDao;
import com.haoxuer.discover.trade.data.dao.TradeAccountDao;
import com.haoxuer.discover.trade.data.dao.TradeStreamDao;
import com.haoxuer.discover.trade.data.entity.TradeAccount;
import com.haoxuer.discover.trade.data.entity.TradeStream;
import com.haoxuer.discover.trade.data.enums.ChangeType;
import com.nbsaas.nbmall.customer.api.apis.CustomerApi;
import com.nbsaas.nbmall.customer.api.domain.list.CustomerList;
import com.nbsaas.nbmall.customer.api.domain.page.CustomerPage;
import com.nbsaas.nbmall.customer.api.domain.request.*;
import com.nbsaas.nbmall.customer.api.domain.response.CustomerResponse;
import com.nbsaas.nbmall.customer.data.dao.CustomerDao;
import com.nbsaas.nbmall.customer.data.entity.Customer;
import com.nbsaas.nbmall.customer.rest.convert.CustomerResponseConvert;
import com.nbsaas.nbmall.customer.rest.convert.CustomerSimpleConvert;
import com.haoxuer.bigworld.tenant.data.entity.Tenant;
import com.haoxuer.discover.config.utils.ConverResourceUtils;
import com.haoxuer.discover.data.page.Filter;
import com.haoxuer.discover.data.page.Order;
import com.haoxuer.discover.data.page.Page;
import com.haoxuer.discover.data.page.Pageable;
import com.haoxuer.discover.data.utils.FilterUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import com.haoxuer.bigworld.member.rest.conver.PageableConver;
import com.haoxuer.bigworld.tenant.util.TenantBeanUtils;
import com.haoxuer.bigworld.company.data.dao.EmployeeDao;
import com.haoxuer.discover.area.data.dao.AreaDao;
import com.haoxuer.discover.area.data.dao.AreaDao;
import com.haoxuer.discover.area.data.dao.AreaDao;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

@Transactional
@Component
public class CustomerResource implements CustomerApi {

    @Autowired
    private CustomerDao dataDao;

    @Autowired
    private EmployeeDao managerDao;
    @Autowired
    private AreaDao provinceDao;
    @Autowired
    private AreaDao areaDao;
    @Autowired
    private AreaDao cityDao;

    @Autowired
    private TradeStreamDao streamDao;

    @Autowired
    private TradeAccountDao tradeAccountDao;

    @Autowired
    private BasicTradeAccountDao basicTradeAccountDao;

    @Autowired
    private TenantUserDao userDao;


    @Override
    public CustomerResponse create(CustomerDataRequest request) {
        CustomerResponse result = new CustomerResponse();

        Customer bean = new Customer();
        bean.setTenant(Tenant.fromId(request.getTenant()));
        handleData(request, bean);
        dataDao.save(bean);
        result = new CustomerResponseConvert().conver(bean);
        return result;
    }

    @Override
    public CustomerResponse register(CustomerDataRequest request) {
        CustomerResponse result = new CustomerResponse();
        if (StringUtils.isEmpty(request.getPhone())) {
            result.setCode(501);
            result.setMsg("手机号不能为空");
            return result;
        }
        UserRegisterRequest reg = new UserRegisterRequest();
        reg.setBindType(BindType.phone);
        reg.setUsername(request.getPhone());
        reg.setPassword(request.getPassword());
        reg.setTenant(request.getTenant());
        UserBasicResponse response = userDao.register(reg);
        if (response.getCode() != 0) {
            result.setCode(502);
            result.setMsg("该手机号已经注册");
            return result;
        }
        Customer customer = dataDao.findById(response.getId());
        if (customer != null) {
            handleData(request, customer);
            result = new CustomerResponseConvert().conver(customer);
        }
        return result;
    }

    @Override
    public TradeStreamPage stream(CustomerSearchRequest request) {
        TradeStreamPage result = new TradeStreamPage();
        if (request.getUser() == null) {
            result.setCode(501);
            result.setMsg("无效token");
            return result;
        }
        Customer member = dataDao.findById(request.getUser());
        if (member == null) {
            result.setCode(1001);
            result.setMsg("无效token");
            return result;
        }
        TradeAccount account = member.getTradeAccount();
        if (account == null) {
            account = tradeAccountDao.initNormal();
            member.setTradeAccount(account);
        }
        result.setMoney(account.getAmount());
        Pageable pageable = new PageableConver().conver(request);
        pageable.getFilters().addAll(FilterUtils.getFilters(request));
        pageable.getOrders().add(Order.desc("id"));
        pageable.getFilters().add(Filter.eq("account.id", account.getId()));

        Page<TradeStream> page = streamDao.page(pageable);
        ConverResourceUtils.converPage(result, page, new TradeStreamSimpleConver());
        return result;
    }

    @Override
    public TradeStreamPage scores(CustomerSearchRequest request) {
        TradeStreamPage result = new TradeStreamPage();
        if (request.getUser() == null) {
            result.setCode(501);
            result.setMsg("无效token");
            return result;
        }
        Customer member = dataDao.findById(request.getUser());
        if (member == null) {
            result.setCode(1001);
            result.setMsg("无效token");
            return result;
        }
        TradeAccount account = member.getScore();
        if (account == null) {
            account = tradeAccountDao.initNormal();
            member.setScore(account);
        }
        result.setMoney(account.getAmount());
        Pageable pageable = new PageableConver().conver(request);
        pageable.getFilters().addAll(FilterUtils.getFilters(request));
        pageable.getFilters().add(Filter.eq("account.id", account.getId()));
        pageable.getOrders().add(Order.desc("id"));
        Page<TradeStream> page = streamDao.page(pageable);
        ConverResourceUtils.converPage(result, page, new TradeStreamSimpleConver());
        return result;
    }

    @Override
    public CustomerResponse rechargeScore(CustomerDataRequest request) {
        CustomerResponse result = new CustomerResponse();
        Customer member = dataDao.findById(request.getUser());
        if (member == null) {
            result.setCode(1001);
            result.setMsg("无效token");
            return result;
        }
        TradeAccount account = member.getScore();
        if (account == null) {
            account = tradeAccountDao.initNormal();
            member.setScore(account);
        }
        TradeAccount scoreAccount = basicTradeAccountDao.special("rechargeScore");
        TradeRequest tradeRequest = new TradeRequest();
        tradeRequest.setAmount(request.getScore());
        tradeRequest.setNote(request.getNote());
        tradeRequest.setTo(account.getId());
        tradeRequest.setFrom(scoreAccount.getId());
        tradeRequest.setChangeType(ChangeType.from(1, ""));
        TradeResponse response = tradeAccountDao.trade(tradeRequest);
        result.setCode(response.getCode());
        result.setMsg(response.getMsg());
        return result;
    }

    @Override
    public CustomerResponse update(CustomerDataRequest request) {
        CustomerResponse result = new CustomerResponse();
        if (request.getId() == null) {
            result.setCode(501);
            result.setMsg("无效id");
            return result;
        }
        Customer bean = dataDao.findById(request.getId());
        if (bean == null) {
            result.setCode(502);
            result.setMsg("无效id");
            return result;
        }
        handleData(request, bean);
        result = new CustomerResponseConvert().conver(bean);
        return result;
    }

    private void handleData(CustomerDataRequest request, Customer bean) {
        TenantBeanUtils.copyProperties(request, bean);
        if (request.getArea() != null) {
            bean.setArea(areaDao.findById(request.getArea()));
        }
        if (request.getCity() != null) {
            bean.setCity(cityDao.findById(request.getCity()));
        }
        if (request.getManager() != null) {
            bean.setManager(managerDao.findById(request.getManager()));
        }
        if (request.getProvince() != null) {
            bean.setProvince(provinceDao.findById(request.getProvince()));
        }

    }

    @Override
    public CustomerResponse delete(CustomerDataRequest request) {
        CustomerResponse result = new CustomerResponse();
        if (request.getId() == null) {
            result.setCode(501);
            result.setMsg("无效id");
            return result;
        }
        dataDao.deleteById(request.getTenant(), request.getId());
        return result;
    }

    @Override
    public CustomerResponse view(CustomerDataRequest request) {
        CustomerResponse result = new CustomerResponse();
        Customer bean = dataDao.findById(request.getTenant(), request.getId());
        if (bean == null) {
            result.setCode(1000);
            result.setMsg("无效id");
            return result;
        }
        result = new CustomerResponseConvert().conver(bean);
        return result;
    }

    @Override
    public CustomerList list(CustomerSearchRequest request) {
        CustomerList result = new CustomerList();

        List<Filter> filters = new ArrayList<>();
        filters.add(Filter.eq("tenant.id", request.getTenant()));
        filters.addAll(FilterUtils.getFilters(request));
        List<Order> orders = new ArrayList<>();
        if ("asc".equals(request.getSortMethod())) {
            orders.add(Order.asc("" + request.getSortField()));
        } else if ("desc".equals(request.getSortMethod())) {
            orders.add(Order.desc("" + request.getSortField()));
        } else {
            orders.add(Order.desc("id"));
        }
        List<Customer> organizations = dataDao.list(0, request.getSize(), filters, orders);

        CustomerSimpleConvert convert = new CustomerSimpleConvert();
        ConverResourceUtils.converList(result, organizations, convert);
        return result;
    }

    @Override
    public CustomerPage search(CustomerSearchRequest request) {
        CustomerPage result = new CustomerPage();
        Pageable pageable = new PageableConver().conver(request);
        pageable.getFilters().addAll(FilterUtils.getFilters(request));
        pageable.getFilters().add(Filter.eq("tenant.id", request.getTenant()));
        if ("asc".equals(request.getSortMethod())) {
            pageable.getOrders().add(Order.asc("" + request.getSortField()));
        } else if ("desc".equals(request.getSortMethod())) {
            pageable.getOrders().add(Order.desc("" + request.getSortField()));
        } else {
            pageable.getOrders().add(Order.desc("id"));
        }
        Page<Customer> page = dataDao.page(pageable);

        CustomerSimpleConvert convert = new CustomerSimpleConvert();
        ConverResourceUtils.converPage(result, page, convert);
        return result;
    }
}
